using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace EuropeEngulfed.NET
{
    //TODO Implement Unit Selection via tooltip
    partial class BlocksToolTip : Form
    {
        List<ProductionMove> newProductionMoves;
        Dictionary<Rectangle, Block> blockPositionList;
        List<Block> blockList;
        bool hideBlocks;
        private const int NUM_BLOCKS_TOOLTIP_ROW = 4;
        private const int TOOLTIP_BLOCK_GAP = 10;
        public enum blocksToolTipMode
        {
            normal,
            axisproduction,
            alliedproduction,
        }
        int germanRemainingWERPs = 0;
        int italianRemainingWERPs = 0;
        int UKRemainingWERPs = 0;
        int frenchRemainingWERPs = 0;
        int USSRRemainingWERPs = 0;
        int USRemainingWERPs = 0;
        blocksToolTipMode toolTipMode = blocksToolTipMode.normal;
        IGameStateInfoProvider gameStateProvider;
        MapInfo.RegionID regionID = MapInfo.RegionID.Albania;
        bool UnlimitedReplacements = false;
        List<MapInfo.CountryID> listOfMinorInfantryStepsBuilt;
        MapInfo.CountryID axisMinorStepBuiltLastTurn;
        int remainingRussianConscriptionSteps;
        bool britishProductionPenalty;
        bool russianProductionPenalty;
        bool blocksMovable = false;
        bool draggingBlock = false;
        bool forceClosed = false;

        public bool IsPinned()
        {
            return pinCheckBox.Checked;
        }

        public List<ProductionMove> NewProductionMoves
        {
            get
            {
                return newProductionMoves;
            }
        }

        public BlocksToolTip(IGameStateInfoProvider gameStateProvider, List<Block> blockList, bool hideBlocks, MapInfo.RegionID regionID, bool blocksMovable)
            : this(gameStateProvider, blockList, hideBlocks, regionID)
        {
            if(!hideBlocks)
                this.blocksMovable = blocksMovable;
        }

        public BlocksToolTip(IGameStateInfoProvider gameStateProvider, List<Block> blockList, bool hideBlocks, MapInfo.RegionID regionID)
        {
            int column = 0;
            int row = 0;
            InitializeComponent();
            blockPositionList = new Dictionary<Rectangle, Block>();
            newProductionMoves = new List<ProductionMove>();
            this.regionID = regionID;
            this.regionLabel.Text = Enum.GetName(typeof(MapInfo.RegionID), regionID);
            foreach (Block block in blockList)
            {
                Rectangle blockRect = new Rectangle(TOOLTIP_BLOCK_GAP + column * (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Width), TOOLTIP_BLOCK_GAP + row * (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Height), PlayingPieceGraphics.GetBlockSize().Width, PlayingPieceGraphics.GetBlockSize().Height);
                blockPositionList.Add(blockRect, block);
                column++;
                if (column == NUM_BLOCKS_TOOLTIP_ROW)
                {
                    column = 0;
                    row++;
                }
            }
            this.blockList = blockList;
            this.Paint += new PaintEventHandler(BlocksToolTip_Paint);
            this.hideBlocks = hideBlocks;
            this.Size = new Size(Math.Min(TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Width / 2 + blockList.Count * (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Width),
                PlayingPieceGraphics.GetBlockSize().Width / 2 + TOOLTIP_BLOCK_GAP + NUM_BLOCKS_TOOLTIP_ROW * (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Width)),
                TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Height / 2 + (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Height) * ((blockList.Count - 1)/ NUM_BLOCKS_TOOLTIP_ROW + 1));
            this.pinCheckBox.Left = this.Width - this.pinCheckBox.Width - 10;
            this.pinCheckBox.Top = 2;
            //this.regionLabel.Top = this.Height - this.regionLabel.Height - 15;
            newProductionMoves = new List<ProductionMove>();
            this.gameStateProvider = gameStateProvider;
        }

        public BlocksToolTip(IGameStateInfoProvider gameStateProvider, List<Block> blockList, bool hideBlocks, int germanRemainingWERPs, int italianRemainingWERPs, MapInfo.RegionID regionID, bool UnlimitedReplacements, List<MapInfo.CountryID> listOfMinorInfantryStepsBuilt, MapInfo.CountryID axisMinorStepBuiltLastTurn)
            : this(gameStateProvider,blockList,hideBlocks,regionID)
        {
            toolTipMode = blocksToolTipMode.axisproduction;
            this.germanRemainingWERPs = germanRemainingWERPs;
            this.italianRemainingWERPs = italianRemainingWERPs;
            this.UnlimitedReplacements = UnlimitedReplacements;
            this.listOfMinorInfantryStepsBuilt = listOfMinorInfantryStepsBuilt;
            this.axisMinorStepBuiltLastTurn = axisMinorStepBuiltLastTurn;
        }

        public BlocksToolTip(IGameStateInfoProvider gameStateProvider, List<Block> blockList, bool hideBlocks, int UKRemainingWERPs, int frenchRemainingWERPs, int USSRRemainingWERPs, int USRemainingWERPs, MapInfo.RegionID regionID, bool UnlimitedReplacements, List<MapInfo.CountryID> listOfMinorInfantryStepsBuilt, int remainingRussianConscriptionSteps, bool britishProductionPenalty, bool russianProductionPenalty)
            : this(gameStateProvider, blockList, hideBlocks, regionID)
        {
            toolTipMode = blocksToolTipMode.alliedproduction;
            this.UKRemainingWERPs = UKRemainingWERPs;
            this.frenchRemainingWERPs = frenchRemainingWERPs;
            this.USSRRemainingWERPs = USSRRemainingWERPs;
            this.remainingRussianConscriptionSteps = remainingRussianConscriptionSteps;
            this.USRemainingWERPs = USRemainingWERPs;
            this.regionID = regionID;
            this.UnlimitedReplacements = UnlimitedReplacements;
            this.listOfMinorInfantryStepsBuilt = listOfMinorInfantryStepsBuilt;
            this.britishProductionPenalty = britishProductionPenalty;
            this.russianProductionPenalty = russianProductionPenalty;
        }

        void BlocksToolTip_Paint(object sender, PaintEventArgs e)
        {
            int column = 0;
            int row = 0;

            foreach (Block block in blockList)
            {
                Point ptToDrawAt = new Point(TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Width / 2 + column * (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Width), TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Height /2 + row * (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Height));
                PlayingPieceGraphics.PaintBlock(e.Graphics, block, ptToDrawAt, 1, hideBlocks);
                column++;
                if(column == NUM_BLOCKS_TOOLTIP_ROW)
                {
                    column = 0;
                    row++;
                }
            }
        }

        private void BlocksToolTip_MouseClick(object sender, MouseEventArgs e)
        {
            if(toolTipMode == blocksToolTipMode.alliedproduction || toolTipMode == blocksToolTipMode.axisproduction)
            {
                if (e.Button == MouseButtons.Right)
                {
                    if (!hideBlocks)
                    {
                        foreach (Rectangle rect in blockPositionList.Keys)
                        {
                            if (rect.Contains(e.Location))
                            {
                                if (blockPositionList[rect].CurrentStrength < blockPositionList[rect].MaxStrength)
                                {
                                    if (toolTipMode == blocksToolTipMode.axisproduction)
                                    {
                                        if (gameStateProvider.CanAxisBlockReceiveReplacement(blockPositionList[rect], regionID))
                                        {
                                            if (blockPositionList[rect].CountryOwner == MapInfo.CountryID.Italy)
                                            {
                                                if ((italianRemainingWERPs - ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType())) >= 0)
                                                {
                                                    newProductionMoves.Add(ProductionMove.CreateBlockReplacementMove(gameStateProvider.GetCurrentGameDate(), gameStateProvider.GetCurrentGamePhase(), MapInfo.CountryID.Italy, blockPositionList[rect].getBlockType(), (int)blockPositionList[rect].CurrentStrength, regionID, blockPositionList[rect].MaxStrength));
                                                    blockPositionList[rect].CurrentStrength++;
                                                    italianRemainingWERPs -= ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType());
                                                    this.Invalidate();
                                                }
                                            }
                                            else
                                            {
                                                if (blockPositionList[rect].CountryOwner == MapInfo.CountryID.Germany || MapInfo.IsAxisMinorPower(blockPositionList[rect].CountryOwner))
                                                {
                                                    bool axisMinorFreeStepAdded = false;
                                                    if(MapInfo.IsAxisMinorPower(blockPositionList[rect].CountryOwner))
                                                    {
                                                        if(blockPositionList[rect].CountryOwner != this.axisMinorStepBuiltLastTurn)
                                                        {
                                                            bool submittedMovesContainsFreeStep = false;
                                                            foreach (ProductionMove productionMove in newProductionMoves)
                                                            {
                                                                if (MapInfo.IsAxisMinorPower(productionMove.Country) && productionMove.Country != this.axisMinorStepBuiltLastTurn)
                                                                {
                                                                    if (productionMove.ProductionBlockType == Block.BlockType.infantry)
                                                                    {
                                                                        submittedMovesContainsFreeStep = true;
                                                                        break;
                                                                    }
                                                                }
                                                            }

                                                            foreach (MapInfo.CountryID minorCountryInfantryBuilt in listOfMinorInfantryStepsBuilt)
                                                            {
                                                                if (MapInfo.IsAxisMinorPower(minorCountryInfantryBuilt) && minorCountryInfantryBuilt != this.axisMinorStepBuiltLastTurn)
                                                                {
                                                                    submittedMovesContainsFreeStep = true;
                                                                    break;
                                                                }
                                                            }

                                                            if (!submittedMovesContainsFreeStep && blockPositionList[rect].IsInfantryClass())
                                                            {
                                                                newProductionMoves.Add(ProductionMove.CreateBlockReplacementMove(gameStateProvider.GetCurrentGameDate(), gameStateProvider.GetCurrentGamePhase(), blockPositionList[rect].CountryOwner, blockPositionList[rect].getBlockType(), (int)blockPositionList[rect].CurrentStrength, regionID, blockPositionList[rect].MaxStrength));
                                                                blockPositionList[rect].CurrentStrength++;
                                                                this.Invalidate();
                                                                axisMinorFreeStepAdded = true;
                                                            }
                                                        }
                                                    }

                                                    if(!axisMinorFreeStepAdded)
                                                    {
                                                        if ((germanRemainingWERPs - ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType())) >= 0)
                                                        {
                                                            newProductionMoves.Add(ProductionMove.CreateBlockReplacementMove(gameStateProvider.GetCurrentGameDate(), gameStateProvider.GetCurrentGamePhase(), blockPositionList[rect].CountryOwner, blockPositionList[rect].getBlockType(), (int)blockPositionList[rect].CurrentStrength, regionID, blockPositionList[rect].MaxStrength));
                                                            blockPositionList[rect].CurrentStrength++;
                                                            germanRemainingWERPs -= ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType());
                                                            this.Invalidate();
                                                        }
                                                    }
                                                }
                                                else if(gameStateProvider.IsAxisCountry(blockPositionList[rect].CountryOwner))
                                                {
                                                    if (!listOfMinorInfantryStepsBuilt.Contains(blockPositionList[rect].CountryOwner))
                                                    {
                                                        if (blockPositionList[rect].getBlockType() == Block.BlockType.infantry)
                                                        {
                                                            bool newMovesContainsFreeStep = false;
                                                            foreach (ProductionMove productionMove in newProductionMoves)
                                                            {
                                                                if (productionMove.Country == blockPositionList[rect].CountryOwner)
                                                                {
                                                                    if (productionMove.ProductionBlockType == Block.BlockType.infantry)
                                                                    {
                                                                        newMovesContainsFreeStep = true;
                                                                    }
                                                                }
                                                            }

                                                            if (!newMovesContainsFreeStep)
                                                            {
                                                                newProductionMoves.Add(ProductionMove.CreateBlockReplacementMove(gameStateProvider.GetCurrentGameDate(), gameStateProvider.GetCurrentGamePhase(), blockPositionList[rect].CountryOwner, blockPositionList[rect].getBlockType(), (int)blockPositionList[rect].CurrentStrength, regionID, blockPositionList[rect].MaxStrength));
                                                                blockPositionList[rect].CurrentStrength++;
                                                                this.Invalidate();
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    else if(toolTipMode == blocksToolTipMode.alliedproduction)
                                    {
                                        if (gameStateProvider.CanAlliedBlockReceiveReplacement(blockPositionList[rect], regionID))
                                        {
                                            if (blockPositionList[rect].CountryOwner == MapInfo.CountryID.GreatBritain)
                                            {
                                                if ((UKRemainingWERPs - ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType(), britishProductionPenalty)) >= 0)
                                                {
                                                    newProductionMoves.Add(ProductionMove.CreateBlockReplacementMove(gameStateProvider.GetCurrentGameDate(), gameStateProvider.GetCurrentGamePhase(), MapInfo.CountryID.GreatBritain, blockPositionList[rect].getBlockType(), (int)blockPositionList[rect].CurrentStrength, regionID, blockPositionList[rect].MaxStrength));
                                                    blockPositionList[rect].CurrentStrength++;
                                                    UKRemainingWERPs -= ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType());
                                                    this.Invalidate();
                                                }
                                            }
                                            else if (blockPositionList[rect].CountryOwner == MapInfo.CountryID.France)
                                            {
                                                if ((frenchRemainingWERPs - ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType())) >= 0)
                                                {
                                                    newProductionMoves.Add(ProductionMove.CreateBlockReplacementMove(gameStateProvider.GetCurrentGameDate(), gameStateProvider.GetCurrentGamePhase(), MapInfo.CountryID.France, blockPositionList[rect].getBlockType(), (int)blockPositionList[rect].CurrentStrength, regionID, blockPositionList[rect].MaxStrength));
                                                    blockPositionList[rect].CurrentStrength++;
                                                    frenchRemainingWERPs -= ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType());
                                                    this.Invalidate();
                                                }
                                            }
                                            else if (blockPositionList[rect].CountryOwner == MapInfo.CountryID.USSR)
                                            {
                                                if(blockPositionList[rect].getBlockType() == Block.BlockType.infantry && this.remainingRussianConscriptionSteps > 0)
                                                {
                                                    ProductionMove productionMoveToAdd = ProductionMove.CreateBlockReplacementMove(gameStateProvider.GetCurrentGameDate(), gameStateProvider.GetCurrentGamePhase(), MapInfo.CountryID.USSR, blockPositionList[rect].getBlockType(), (int)blockPositionList[rect].CurrentStrength, regionID, blockPositionList[rect].MaxStrength);
                                                    productionMoveToAdd.RussianEmergencyConscription = true;
                                                    newProductionMoves.Add(productionMoveToAdd);
                                                    blockPositionList[rect].CurrentStrength++;
                                                    this.remainingRussianConscriptionSteps--;
                                                    this.Invalidate();
                                                }
                                                else if ((USSRRemainingWERPs - ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType(), russianProductionPenalty)) >= 0)
                                                {
                                                    newProductionMoves.Add(ProductionMove.CreateBlockReplacementMove(gameStateProvider.GetCurrentGameDate(), gameStateProvider.GetCurrentGamePhase(), MapInfo.CountryID.USSR, blockPositionList[rect].getBlockType(), (int)blockPositionList[rect].CurrentStrength, regionID, blockPositionList[rect].MaxStrength));
                                                    blockPositionList[rect].CurrentStrength++;
                                                    USSRRemainingWERPs -= ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType());
                                                    this.Invalidate();
                                                }
                                            }
                                            else if (blockPositionList[rect].CountryOwner == MapInfo.CountryID.USA || blockPositionList[rect].CountryOwner == MapInfo.CountryID.FreeFrance)
                                            {
                                                if ((USRemainingWERPs - ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType())) >= 0)
                                                {
                                                    newProductionMoves.Add(ProductionMove.CreateBlockReplacementMove(gameStateProvider.GetCurrentGameDate(), gameStateProvider.GetCurrentGamePhase(), blockPositionList[rect].CountryOwner, blockPositionList[rect].getBlockType(), (int)blockPositionList[rect].CurrentStrength, regionID, blockPositionList[rect].MaxStrength));
                                                    blockPositionList[rect].CurrentStrength++;
                                                    USRemainingWERPs -= ProductionMove.GetBlockCost(blockPositionList[rect].getBlockType());
                                                    this.Invalidate();
                                                }
                                            }
                                            else if(gameStateProvider.IsAlliedCountry(blockPositionList[rect].CountryOwner))
                                            {
                                                if(!listOfMinorInfantryStepsBuilt.Contains(blockPositionList[rect].CountryOwner))
                                                {
                                                    if(blockPositionList[rect].getBlockType() == Block.BlockType.infantry)
                                                    {
                                                        bool newMovesContainsFreeStep = false;
                                                        foreach (ProductionMove productionMove in newProductionMoves)
                                                        {
                                                            if (productionMove.Country == blockPositionList[rect].CountryOwner)
                                                            {
                                                                if (productionMove.ProductionBlockType == Block.BlockType.infantry)
                                                                {
                                                                    newMovesContainsFreeStep = true;
                                                                }
                                                            }
                                                        }

                                                        if (!newMovesContainsFreeStep)
                                                        {
                                                            newProductionMoves.Add(ProductionMove.CreateBlockReplacementMove(gameStateProvider.GetCurrentGameDate(), gameStateProvider.GetCurrentGamePhase(), blockPositionList[rect].CountryOwner, blockPositionList[rect].getBlockType(), (int)blockPositionList[rect].CurrentStrength, regionID, blockPositionList[rect].MaxStrength));
                                                            blockPositionList[rect].CurrentStrength++;
                                                            this.Invalidate();
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        private void BlocksToolTip_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (blocksMovable)
                {
                    if(IsPinned())
                    {
                        foreach (Rectangle rect in blockPositionList.Keys)
                        {
                            if (rect.Contains(e.Location))
                            {
                                if (EuropeEngulfedNETForm.MainForm.CanBlockBeDragged(blockPositionList[rect], regionID))
                                {
                                    Size blockSize = PlayingPieceGraphics.GetBlockSize();
                                    Size blockBackingSize = PlayingPieceGraphics.GetBlockBackingSize();
                                    Bitmap b = new Bitmap(blockBackingSize.Width + PlayingPieceGraphics.BLOCK_BACKING_SIZE, blockBackingSize.Height + PlayingPieceGraphics.BLOCK_BACKING_SIZE);
                                    Graphics g = Graphics.FromImage(b);
                                    PlayingPieceGraphics.PaintBlock(g, blockPositionList[rect], new Point(blockSize.Width / 2, blockSize.Height / 2 + PlayingPieceGraphics.BLOCK_BACKING_SIZE), 1, false);
                                    IntPtr ptr = b.GetHicon();
                                    this.Cursor = new Cursor(ptr);
                                    EuropeEngulfedNETForm.MainForm.SetBlockBeingDragged(blockPositionList[rect], this.regionID);
                                    draggingBlock = true;
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }

        private void BlocksToolTip_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (blocksMovable)
                {
                    if(draggingBlock)
                    {
                        if (e.Location.X < 0 || e.Location.X > this.Width || e.Location.Y < 0 || e.Location.Y > this.Height)
                        {
                            int column = 0;
                            int row = 0;
                            MouseEventArgs newMouseEvent = new MouseEventArgs(e.Button, e.Clicks, e.Location.X + this.Left, e.Location.Y + this.Top, e.Delta);
                            EuropeEngulfedNETForm.MainForm.RaiseMapControlMouseUp(sender, newMouseEvent);
                            this.Cursor = Cursors.Default;
                            draggingBlock = false;
                            this.blockList = EuropeEngulfedNETForm.MainForm.GetBlockToolTipUpdatedBlockList();
                            if (this.blockList != null && this.blockList.Count > 1)
                            {
                                blockPositionList.Clear();
                                foreach (Block block in blockList)
                                {
                                    Rectangle blockRect = new Rectangle(TOOLTIP_BLOCK_GAP + column * (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Width), TOOLTIP_BLOCK_GAP + row * (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Height), PlayingPieceGraphics.GetBlockSize().Width, PlayingPieceGraphics.GetBlockSize().Height);
                                    blockPositionList.Add(blockRect, block);
                                    column++;
                                    if (column == NUM_BLOCKS_TOOLTIP_ROW)
                                    {
                                        column = 0;
                                        row++;
                                    }
                                }

                                this.Size = new Size(Math.Min(TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Width / 2 + blockList.Count * (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Width),
                                            PlayingPieceGraphics.GetBlockSize().Width / 2 + TOOLTIP_BLOCK_GAP + NUM_BLOCKS_TOOLTIP_ROW * (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Width)),
                                            TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Height / 2 + (TOOLTIP_BLOCK_GAP + PlayingPieceGraphics.GetBlockSize().Height) * ((blockList.Count - 1) / NUM_BLOCKS_TOOLTIP_ROW + 1));
                                this.pinCheckBox.Left = this.Width - this.pinCheckBox.Width - 10;
                                this.pinCheckBox.Top = 2;
                                //this.regionLabel.Top = this.Height - this.regionLabel.Height - 2;
                                this.Invalidate();
                            }
                            else
                            {
                                forceClosed = true;
                                this.Close();
                            }
                        }
                        else
                        {
                            this.Cursor = Cursors.Default;
                            draggingBlock = false;
                        }
                    }
                }
            }
        }

        private void BlocksToolTip_FormClosed(object sender, FormClosedEventArgs e)
        {
            if(forceClosed)
            {
                EuropeEngulfedNETForm.MainForm.ClearBlockToolTipRef();
                this.Dispose();
            }
        }
    }
}